# 项目初始化脚本 (PowerShell)
# 用于快速配置开发环境：安装依赖、配置 Git hooks、生成 .env 文件

# 错误处理设置
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest

# 退出码定义
$EXIT_SUCCESS = 0
$EXIT_PREREQUISITES_MISSING = 1
$EXIT_VERSION_MISMATCH = 2
$EXIT_DEPENDENCY_FAILED = 3
$EXIT_HOOKS_FAILED = 4
$EXIT_CONFIG_FAILED = 5

# 颜色输出辅助函数
function Write-Success {
    param([string]$Message)
    Write-Host "✅ $Message" -ForegroundColor Green
}

function Write-Info {
    param([string]$Message)
    Write-Host "📝 $Message" -ForegroundColor Cyan
}

function Write-Warning {
    param([string]$Message)
    Write-Host "⚠️  $Message" -ForegroundColor Yellow
}

function Write-Failure {
    param([string]$Message)
    Write-Host "❌ $Message" -ForegroundColor Red
}

function Write-Step {
    param([string]$Message)
    Write-Host "$Message" -ForegroundColor Blue
}

# 路径规范化函数（确保使用 Windows 风格的反斜杠）
function Normalize-Path {
    param([string]$Path)
    # 将正斜杠转换为反斜杠（Windows 标准）
    return $Path -replace '/', '\'
}

# 检测平台信息
function Get-PlatformInfo {
    $osVersion = [System.Environment]::OSVersion
    $psVersion = $PSVersionTable.PSVersion
    return "Windows (PowerShell $($psVersion.Major).$($psVersion.Minor))"
}

# 规范化环境变量中的路径（确保 Windows 路径格式）
function Initialize-EnvironmentPaths {
    # 确保环境变量中的路径使用 Windows 格式
    # PowerShell 通常已经正确处理，但我们确保一致性
    if ($env:PATH) {
        $env:PATH = $env:PATH -replace '/', '\'
    }
}

# 检查初始化状态
function Test-InitializationStatus {
    $envExists = Test-Path ".env"
    $hooksExist = Test-Path ".git\hooks\pre-commit"
    $lockExists = Test-Path "uv.lock"

    if ($envExists -and $hooksExist -and $lockExists) {
        return "INITIALIZED"
    }
    elseif ($envExists -or $hooksExist -or $lockExists) {
        return "PARTIALLY_INITIALIZED"
    }
    else {
        return "UNINITIALIZED"
    }
}

# 检查命令是否存在
function Test-CommandExists {
    param([string]$Command)
    try {
        $null = Get-Command $Command -ErrorAction Stop
        return $true
    }
    catch {
        return $false
    }
}

# 检查前置条件
function Test-Prerequisites {
    Write-Step "🔍 检查前置条件..."

    # 检查 PowerShell 版本
    $psVersion = $PSVersionTable.PSVersion
    if ($psVersion.Major -lt 5 -or ($psVersion.Major -eq 5 -and $psVersion.Minor -lt 1)) {
        Write-Failure "需要 PowerShell 5.1 或更高版本，当前版本: $($psVersion.Major).$($psVersion.Minor)"
        Write-Info "请访问 https://docs.microsoft.com/powershell/scripting/install/installing-powershell-on-windows 升级 PowerShell"
        exit $EXIT_VERSION_MISMATCH
    }
    Write-Host "  - PowerShell: $($psVersion.Major).$($psVersion.Minor).$($psVersion.Patch)" -ForegroundColor Gray

    # 检查 Python
    if (-not (Test-CommandExists "python")) {
        Write-Failure "未找到 Python"
        Write-Info "请访问 https://www.python.org/downloads/ 安装 Python 3.12+"
        exit $EXIT_PREREQUISITES_MISSING
    }

    # 检查 Python 版本
    try {
        $pythonVersion = python --version 2>&1 | Out-String
        if ($pythonVersion -match "Python (\d+)\.(\d+)") {
            $major = [int]$matches[1]
            $minor = [int]$matches[2]

            if ($major -lt 3 -or ($major -eq 3 -and $minor -lt 12)) {
                Write-Failure "需要 Python 3.12+，当前版本: $($matches[0])"
                Write-Info "请访问 https://www.python.org/downloads/ 升级 Python"
                Write-Info "或使用 pyenv 管理 Python 版本: https://github.com/pyenv/pyenv"
                exit $EXIT_VERSION_MISMATCH
            }

            Write-Host "  - Python: $($matches[0])" -ForegroundColor Gray
        }
    }
    catch {
        Write-Failure "无法检测 Python 版本"
        exit $EXIT_PREREQUISITES_MISSING
    }

    # 检查 UV
    if (-not (Test-CommandExists "uv")) {
        Write-Failure "未检测到 UV 包管理器"
        Write-Info ""
        Write-Info "请访问以下链接安装 UV:"
        Write-Info "  https://docs.astral.sh/uv/getting-started/installation/"
        Write-Info ""
        Write-Info "快速安装命令 (PowerShell):"
        Write-Info '  irm https://astral.sh/uv/install.ps1 | iex'
        exit $EXIT_PREREQUISITES_MISSING
    }

    $uvVersion = uv --version 2>&1 | Out-String
    Write-Host "  - UV: $uvVersion".Trim() -ForegroundColor Gray

    # 检查 Git
    if (-not (Test-CommandExists "git")) {
        Write-Warning "未检测到 Git（可选）"
        Write-Info "如需 Git hooks，请访问: https://git-scm.com/downloads"
    }
    else {
        $gitVersion = git --version 2>&1 | Out-String
        Write-Host "  - Git: $gitVersion".Trim() -ForegroundColor Gray
    }

    Write-Success "环境检测通过"
}

# 安装项目依赖
function Install-Dependencies {
    Write-Step "📦 正在安装项目依赖..."

    try {
        uv sync
        if ($LASTEXITCODE -ne 0) {
            throw "uv sync 返回错误码: $LASTEXITCODE"
        }
        Write-Success "依赖安装完成！"
    }
    catch {
        Write-Failure "依赖安装失败"
        Write-Info ""
        Write-Info "可能的原因:"
        Write-Info "  - 网络连接问题"
        Write-Info "  - pyproject.toml 配置错误"
        Write-Info "  - 磁盘空间不足"
        Write-Info ""
        Write-Info "建议操作:"
        Write-Info "  1. 检查网络连接"
        Write-Info "  2. 手动运行: uv sync --verbose"
        Write-Info "  3. 查看详细错误日志"
        exit $EXIT_DEPENDENCY_FAILED
    }
}

# 安装 Git hooks
function Install-GitHooks {
    if (-not (Test-Path ".git")) {
        Write-Warning "未检测到 Git 仓库，跳过 hooks 配置"
        return
    }

    Write-Step "🪝 正在配置 Git hooks..."

    try {
        uv run pre-commit install
        if ($LASTEXITCODE -ne 0) {
            throw "pre-commit install 返回错误码: $LASTEXITCODE"
        }
        Write-Success "Git hooks 配置完成！"
    }
    catch {
        Write-Failure "Git hooks 安装失败"
        Write-Info ""
        Write-Info "建议操作:"
        Write-Info "  1. 检查 .git 目录权限"
        Write-Info "  2. 手动运行: uv run pre-commit install"
        exit $EXIT_HOOKS_FAILED
    }
}

# 配置项目信息
function Set-ProjectInfo {
    param(
        [bool]$Interactive = $true
    )

    Write-Step "📋 配置项目信息..."

    $projectName = ""
    $projectDescription = ""

    if ($Interactive) {
        # 读取当前配置
        $currentName = "fastapi-demo"
        $currentDesc = "基于 FastAPI 的演示项目, 遵循最佳实践"

        if (Test-Path "pyproject.toml") {
            $pyprojectContent = Get-Content "pyproject.toml" -Raw
            if ($pyprojectContent -match 'name\s*=\s*"([^"]+)"') {
                $currentName = $matches[1]
            }
            if ($pyprojectContent -match 'description\s*=\s*"([^"]+)"') {
                $currentDesc = $matches[1]
            }
        }

        Write-Host ""
        Write-Host "当前项目名称: $currentName" -ForegroundColor Gray
        $inputName = Read-Host "请输入新项目名称 (留空保持不变)"
        if ($inputName) {
            $projectName = $inputName
        } else {
            $projectName = $currentName
        }

        Write-Host "当前项目描述: $currentDesc" -ForegroundColor Gray
        $inputDesc = Read-Host "请输入项目描述 (留空保持不变)"
        if ($inputDesc) {
            $projectDescription = $inputDesc
        } else {
            $projectDescription = $currentDesc
        }
        Write-Host ""
    } else {
        # 非交互模式，使用默认值
        $projectName = "fastapi-demo"
        $projectDescription = "基于 FastAPI 的演示项目, 遵循最佳实践"
    }

    # 返回配置信息
    return @{
        Name = $projectName
        Description = $projectDescription
    }
}

# 更新 pyproject.toml
function Update-PyprojectToml {
    param(
        [string]$Name,
        [string]$Description
    )

    Write-Step "📝 更新 pyproject.toml..."

    try {
        $content = Get-Content "pyproject.toml" -Raw

        # 替换项目名称
        $content = $content -replace '(name\s*=\s*)"[^"]+"', "`$1`"$Name`""

        # 替换项目描述
        $content = $content -replace '(description\s*=\s*)"[^"]+"', "`$1`"$Description`""

        Set-Content "pyproject.toml" -Value $content -NoNewline
        Write-Success "pyproject.toml 更新完成！"
    }
    catch {
        Write-Failure "pyproject.toml 更新失败: $_"
        exit $EXIT_CONFIG_FAILED
    }
}

# 更新 config.py
function Update-ConfigPy {
    param(
        [string]$Name,
        [string]$Description
    )

    Write-Step "📝 更新 app/core/config.py..."

    try {
        $configPath = "app\core\config.py"
        $content = Get-Content $configPath -Raw

        # 替换 APP_NAME 默认值（匹配多行模式）
        $content = $content -replace '(APP_NAME:\s*Annotated\[[^\]]+\]\s*=\s*)"[^"]+"', "`$1`"$Name`""

        # 替换 APP_DESCRIPTION 默认值
        $content = $content -replace '(APP_DESCRIPTION:\s*Annotated\[[^\]]+\]\s*=\s*)"[^"]+"', "`$1`"$Description`""

        Set-Content $configPath -Value $content -NoNewline
        Write-Success "config.py 更新完成！"
    }
    catch {
        Write-Failure "config.py 更新失败: $_"
        exit $EXIT_CONFIG_FAILED
    }
}

# 更新 LICENSE
function Update-License {
    param(
        [string]$Name
    )

    Write-Step "📝 更新 LICENSE..."

    if (-not (Test-Path "LICENSE")) {
        Write-Warning "LICENSE 文件不存在，跳过更新"
        return
    }

    try {
        $content = Get-Content "LICENSE" -Raw

        # 将项目名转换为合适的格式（首字母大写）
        $textInfo = (Get-Culture).TextInfo
        $projectTitle = $textInfo.ToTitleCase($Name.Replace('-', ' ').Replace('_', ' '))

        # 替换 LICENSE 中的项目名（匹配 "Copyright (c) YEAR Project Name" 格式）
        $content = $content -replace '(Copyright \(c\) \d{4} ).+', "`$1$projectTitle Project"

        Set-Content "LICENSE" -Value $content -NoNewline
        Write-Success "LICENSE 更新完成！"
    }
    catch {
        Write-Failure "LICENSE 更新失败: $_"
        exit $EXIT_CONFIG_FAILED
    }
}

# 生成配置文件
function New-ConfigFile {
    Write-Step "📝 正在生成配置文件..."

    # 检查 .env 是否已存在
    if (Test-Path ".env") {
        $response = Read-Host "检测到已存在 .env 文件。是否重新生成? (y/N)"
        if ($response -notmatch '^[Yy]') {
            Write-Info "⏭️  跳过 .env 生成"
            return
        }

        # 备份现有文件
        $timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
        $backupFile = ".env.backup.$timestamp"
        Copy-Item ".env" $backupFile
        Write-Info "📦 已备份现有配置到: $backupFile"

        # 清理旧备份（保留最近5个）
        $backups = Get-ChildItem ".env.backup.*" | Sort-Object LastWriteTime -Descending
        if ($backups.Count -gt 5) {
            $backups | Select-Object -Skip 5 | Remove-Item
        }
    }

    # 生成新的 .env 文件
    try {
        uv run -m scripts.generate_env --output .env --quiet
        if ($LASTEXITCODE -ne 0) {
            throw "generate_env.py 返回错误码: $LASTEXITCODE"
        }
        Write-Success ".env 文件生成完成！"
    }
    catch {
        Write-Failure "配置文件生成失败"
        Write-Info ""
        Write-Info "建议操作:"
        Write-Info "  1. 检查 scripts/generate_env.py 是否存在"
        Write-Info "  2. 检查文件系统权限"
        Write-Info "  3. 检查磁盘空间"
        exit $EXIT_CONFIG_FAILED
    }
}

# 生成 .env.example
function New-EnvExample {
    Write-Step "📝 生成 .env.example..."

    try {
        uv run -m scripts.generate_env --output .env.example --quiet
        if ($LASTEXITCODE -ne 0) {
            throw "generate_env.py 返回错误码: $LASTEXITCODE"
        }
        Write-Success ".env.example 生成完成！"
    }
    catch {
        Write-Failure ".env.example 生成失败: $_"
        exit $EXIT_CONFIG_FAILED
    }
}

# 重建 Git 仓库
function Reset-GitRepository {
    Write-Step "🔄 重建 Git 仓库..."

    if (Test-Path ".git") {
        $response = Read-Host "是否重建 Git 仓库? 这将删除所有提交历史 (y/N)"
        if ($response -notmatch '^[Yy]') {
            Write-Info "⏭️  跳过 Git 仓库重建"
            return $false
        }

        # 删除现有 .git 目录
        Write-Warning "正在删除现有 Git 仓库..."
        try {
            Remove-Item ".git" -Recurse -Force
            Write-Info "已删除旧仓库"
        }
        catch {
            Write-Failure "无法删除 .git 目录: $_"
            return $false
        }
    }

    # 初始化新仓库
    try {
        git init
        if ($LASTEXITCODE -ne 0) {
            throw "git init 返回错误码: $LASTEXITCODE"
        }
        Write-Success "Git 仓库初始化完成！"
        return $true
    }
    catch {
        Write-Failure "Git 仓库初始化失败: $_"
        return $false
    }
}

# 主执行流程
function Main {
    # 规范化环境变量路径
    Initialize-EnvironmentPaths

    Write-Host ""
    Write-Host "========================================" -ForegroundColor Magenta
    Write-Host "🚀 FastAPI Demo 项目初始化" -ForegroundColor Magenta
    Write-Host "========================================" -ForegroundColor Magenta
    $platform = Get-PlatformInfo
    Write-Host "平台: $platform" -ForegroundColor Cyan
    Write-Host ""

    # 检查初始化状态
    $status = Test-InitializationStatus
    if ($status -eq "INITIALIZED") {
        Write-Info "✨ 项目已初始化，正在重新配置..."
    }
    elseif ($status -eq "PARTIALLY_INITIALIZED") {
        Write-Info "⚙️  检测到部分初始化，继续配置..."
    }
    else {
        Write-Info "🆕 开始首次初始化..."
    }
    Write-Host ""

    # 执行初始化步骤
    Test-Prerequisites

    # 配置项目信息
    $projectInfo = Set-ProjectInfo -Interactive $true
    Update-PyprojectToml -Name $projectInfo.Name -Description $projectInfo.Description
    Update-ConfigPy -Name $projectInfo.Name -Description $projectInfo.Description
    Update-License -Name $projectInfo.Name

    Install-Dependencies

    # 重建 Git 仓库（可选）
    $gitRebuilt = Reset-GitRepository

    # 如果重建了 Git 仓库或 Git 仓库存在，则安装 hooks
    if ($gitRebuilt -or (Test-Path ".git")) {
        Install-GitHooks
    }

    New-ConfigFile
    New-EnvExample

    # 完成提示
    Write-Host ""
    Write-Host "========================================" -ForegroundColor Magenta
    Write-Host "🎉 项目初始化完成！" -ForegroundColor Green
    Write-Host "========================================" -ForegroundColor Magenta
    Write-Host ""
    Write-Info "项目信息:"
    Write-Host "  名称: $($projectInfo.Name)" -ForegroundColor Cyan
    Write-Host "  描述: $($projectInfo.Description)" -ForegroundColor Cyan
    Write-Host ""
    Write-Info "可以运行以下命令开始开发:"
    Write-Host "  make dev     # 启动开发服务器" -ForegroundColor Cyan
    Write-Host "  make test    # 运行测试" -ForegroundColor Cyan
    Write-Host ""

    exit $EXIT_SUCCESS
}

# 执行主函数
Main
